package com.android.exchangeapp.modle

import android.content.Context
import android.os.Parcelable
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import kotlinx.parcelize.Parcelize
import org.json.JSONArray
import org.json.JSONObject
import java.io.IOException
import java.net.HttpURLConnection
import java.net.URL
import java.util.Collections
import java.util.concurrent.ConcurrentHashMap
import kotlin.jvm.Throws

data class ExchangeResult(
    val date: String,
    val rates: Map<String, Double>
)

@Parcelize
data class SupportCurrency(
    val key: String,
    val currency: String
) : Parcelable

object ExchangeManager {
    private val mCurrencyRateMap = ConcurrentHashMap<String, ExchangeResult?>()
    private val mSupportCurrencyList = mutableListOf<SupportCurrency>()

    suspend fun getSupportCurrency(context: Context): List<SupportCurrency> {
        if (mSupportCurrencyList.isNotEmpty()) {
            return Collections.unmodifiableList(mSupportCurrencyList)
        }
        return withContext(Dispatchers.IO) {
            try {
                val json = context.assets.open("support_exchange.json").readBytes().decodeToString()
                val jsonArray = JSONArray(json)
                for (i in 0..jsonArray.length()) {
                    val item = jsonArray.optJSONArray(i) ?: continue
                    mSupportCurrencyList.add(
                        SupportCurrency(
                            item.optString(0), item.optString(1)
                        )
                    )
                }
            } catch (e: IOException) {
            }
            mSupportCurrencyList
        }
    }

    /**
     * 货币利率
     *
     * @param currency 货币
     */
    suspend fun getCurrencyRate(currency: String): ExchangeResult? {
        val result = mCurrencyRateMap[currency]
        if (result != null) {
            return result
        }
        return withContext(Dispatchers.IO) {
            requestCurrencyRate(currency)
        }
    }

    @Throws(IOException::class)
    private fun requestCurrencyRate(currency: String): ExchangeResult? {
        val connection =
            URL("https://api.exchangerate-api.com/v4/latest/$currency").openConnection() as HttpURLConnection
        connection.requestMethod = "GET"
        if (connection.responseCode == HttpURLConnection.HTTP_OK) {
            val json = connection.inputStream.readBytes().decodeToString()
            val jsonObject = JSONObject(json)
            val rateJsonObject = jsonObject.optJSONObject("rates")
            val rateMap = mutableMapOf<String, Double>()
            rateJsonObject?.keys()?.forEach { name ->
                rateMap[name] = rateJsonObject.optDouble(name)
            }
            return ExchangeResult(
                jsonObject.optString("date", ""),
                rateMap
            ).apply {
                mCurrencyRateMap[currency] = this
            }
        } else {
            return null
        }
    }
}